package ij.umasuo.gui.laserCtr.dstorm;

import ij.IJ;
import ij.umasuo.MyConstants;
import ij.umasuo.MyResource;
import ij.umasuo.MyUserSettings;
import ij.umasuo.AOTFController.DStormCtr;
import ij.umasuo.gui.working.LiveViewer;

import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class DStormEditor  extends JPanel implements ItemListener,ChangeListener, ActionListener{

	private static final long serialVersionUID = 1L;

	private static DStormEditor instance = new DStormEditor();
	DStormCtr dstormCtr = DStormCtr.getInstance();
	//the lasers we need to this 
	private JCheckBox laser405CB = new JCheckBox("405");
	private JCheckBox laser459CB = new JCheckBox("459");
	private JCheckBox laser488CB = new JCheckBox("488");
	private JCheckBox laser532CB = new JCheckBox("532");
	private JCheckBox laser561CB = new JCheckBox("561");
	private JCheckBox laser656CB = new JCheckBox("656");
	
	private JSlider slider405 = new JSlider();
	private JSlider slider459 = new JSlider();
	private JSlider slider488 = new JSlider();
	private JSlider slider532 = new JSlider();
	private JSlider slider561 = new JSlider();
	private JSlider slider656 = new JSlider();
	
	private JLabel label405 = new JLabel("0%");
	private JLabel label459 = new JLabel("0%");
	private JLabel label488 = new JLabel("0%");
	private JLabel label532 = new JLabel("0%");
	private JLabel label561 = new JLabel("0%");
	private JLabel label656 = new JLabel("0%");
	
	private JLabel lblMaxImageCount = new JLabel("Max Image Count:");
	private JTextField tfMaxImageCount =  new JTextField();
	
	private final JButton btnLaser = new JButton("laser");
	private final JButton btnCamera = new JButton("camera");
	
	private boolean isLaserOn = false;
	private boolean isTakingData = false;
	
	private boolean isInit =true; 
	/**
	 * Create the panel
	 */
	public DStormEditor() {
		addComponentListener(new ComponentAdapter() {
			@Override
			public void componentResized(ComponentEvent arg0) {
				resized();
			}
		});
		
		this.setToolTipText("This is the DSTORM setting");
		this.setBorder(new EmptyBorder(0, 0, 0, 0));

		this.setBounds(1, 1, 380, 250);
		this.setLayout(null);
		laser405CB.addItemListener(this);
		laser405CB.setBounds(20, 20, 55, 25);
		add(laser405CB);
		laser459CB.addItemListener(this);
		laser459CB.setBounds(20, 50, 55, 25);
		add(laser459CB);
		laser488CB.addItemListener(this);
		laser488CB.setBounds(20, 80, 55, 25);
		add(laser488CB);
		laser532CB.addItemListener(this);
		laser532CB.setBounds(20, 110, 55, 25);
		add(laser532CB);
		laser561CB.addItemListener(this);
		laser561CB.setBounds(20, 140, 55, 25);
		add(laser561CB);
		laser656CB.addItemListener(this);
		laser656CB.setBounds(20, 170, 55, 25);
		add(laser656CB);
		
		
		slider405.addChangeListener(this);
		slider405.setBounds(81, 22, 200, 23);
		slider405.setValue(0);
		add(slider405);
		slider459.addChangeListener(this);
		slider459.setBounds(81, 50, 200, 23);
		slider459.setValue(0);
		add(slider459);
		slider488.addChangeListener(this);
		slider488.setBounds(81, 81, 200, 23);
		slider488.setValue(0);
		add(slider488);
		slider532.addChangeListener(this);
		slider532.setBounds(81, 110, 200, 23);
		slider532.setValue(0);
		add(slider532);
		slider561.addChangeListener(this);
		slider561.setBounds(81, 142, 200, 23);
		slider561.setValue(0);
		add(slider561);
		slider656.addChangeListener(this);
		slider656.setBounds(81, 172, 200, 23);
		slider656.setValue(0);
		add(slider656);

		label405.setBounds(291, 25, 50, 15);
		add(label405);
		label459.setBounds(291, 55, 50, 15);
		add(label459);
		label488.setBounds(291, 85, 50, 15);
		add(label488);
		label532.setBounds(291, 115, 50, 15);
		add(label532);
		label561.setBounds(291, 145, 50, 15);
		add(label561);
		label656.setBounds(291, 175, 50, 15);
		add(label656);
		btnLaser.setBounds(35, 220, 140, 30);
		
		
		btnLaser.addActionListener(this);
		btnLaser.setBounds(40, 225, 140, 30);
		btnLaser.setHorizontalTextPosition(JLabel.CENTER);
		btnLaser.setBorder(null);
		btnLaser.setIcon(new ImageIcon(MyResource.getGreenButtonBG140()));
		btnLaser.setText("Laser ON");
		btnLaser.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		add(btnLaser);
		
		btnCamera.addActionListener(this);
		btnCamera.setBounds(197, 220, 140, 30);
		btnCamera.setHorizontalTextPosition(JLabel.CENTER);
		btnCamera.setBorder(null);
		btnCamera.setIcon(new ImageIcon(MyResource.getGreenButtonBG140()));
		btnCamera.setText("No Data");
		btnCamera.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
		add(btnCamera);
		
		lblMaxImageCount.setBounds(30, 198, 115, 20);
		add(lblMaxImageCount);
		tfMaxImageCount.setBounds(165, 198, 66, 20);
		add(tfMaxImageCount);
		DStormCtr.getInstance().setViwer(this);
		readFromSettings();
	}
	
	
	 /** 
	  * save settings to UserSetting
	  */
	public void saveSettings() {
		if(isInit) return;
		// clear all the old DSTORM laser settings
		MyUserSettings.dstLaserInt.clear();
		MyUserSettings.dstLasers.clear();
		// add the new settings to the settings
		if (laser405CB.isSelected()) {
			MyUserSettings.addDstCtr("405", slider405.getValue()* MyConstants.LASER_MAX_POWER / 100 + "");
		}
		if (laser459CB.isSelected()) {
			MyUserSettings.addDstCtr("459", slider459.getValue()* MyConstants.LASER_MAX_POWER / 100 + "");
		}
		if (laser488CB.isSelected()) {
			MyUserSettings.addDstCtr("488", slider488.getValue()* MyConstants.LASER_MAX_POWER / 100 + "");
		}
		if (laser532CB.isSelected()) {
			MyUserSettings.addDstCtr("532", slider532.getValue()* MyConstants.LASER_MAX_POWER / 100 + "");
		}
		if (laser561CB.isSelected()) {
			MyUserSettings.addDstCtr("561", slider561.getValue()* MyConstants.LASER_MAX_POWER / 100 + "");
		}
		if (laser656CB.isSelected()) {
			MyUserSettings.addDstCtr("656", slider656.getValue()* MyConstants.LASER_MAX_POWER / 100 + "");
		}
		MyUserSettings.saveSettings();
	}
	
	/**
	 * read the usersettings and show them in the window
	 */
	public void readFromSettings() {
		// create new lasers with the settings
		for (int i = 0; i < MyUserSettings.dstLasers.size(); i++) {
			int laser = Integer.parseInt(MyUserSettings.dstLasers.get(i));
			int power = Integer.parseInt(MyUserSettings.dstLaserInt.get(i));
			switch (laser) {
				case 405: {
					laser405CB.setSelected(true);
					slider405.setValue(power * 100 / MyConstants.LASER_MAX_POWER);
					label405.setText(power * 100 / MyConstants.LASER_MAX_POWER + "%");
					break;
				}
				case 459: {
					laser459CB.setSelected(true);
					slider459.setValue(power * 100 / MyConstants.LASER_MAX_POWER);
					label459.setText(power * 100 / MyConstants.LASER_MAX_POWER + "%");
					break;
				}
				case 488: {
					laser488CB.setSelected(true);
					slider488.setValue(power * 100 / MyConstants.LASER_MAX_POWER);
					label488.setText(power * 100 / MyConstants.LASER_MAX_POWER + "%");
					break;
				}
				case 532: {
					laser532CB.setSelected(true);
					slider532.setValue(power * 100 / MyConstants.LASER_MAX_POWER);
					label532.setText(power * 100 / MyConstants.LASER_MAX_POWER + "%");
					break;
				}
				case 561: {
					laser561CB.setSelected(true);
					slider561.setValue(power * 100 / MyConstants.LASER_MAX_POWER);
					label561.setText(power * 100 / MyConstants.LASER_MAX_POWER + "%");
					break;
				}
				case 656: {
					laser656CB.setSelected(true);
					slider656.setValue(power * 100 / MyConstants.LASER_MAX_POWER);
					label656.setText(power * 100 / MyConstants.LASER_MAX_POWER + "%");
					break;
				}
			}
		}
		
		isInit = false;
	}

	/**
	 * resize the component and reorder the UI
	 */
	public void resized(){
		int width = this.getWidth();
		if(width < 380){
			width = 380;
		}
		slider405.setSize(width- 175, slider405.getHeight());
		label405.setLocation(width - 90, label405.getLocation().y);
		slider459.setSize(width- 175, slider459.getHeight());
		label459.setLocation(width - 90, label459.getLocation().y);
		slider488.setSize(width- 175, slider488.getHeight());
		label488.setLocation(width - 90, label488.getLocation().y);
		slider532.setSize(width- 175, slider532.getHeight());
		label532.setLocation(width - 90, label532.getLocation().y);
		slider561.setSize(width- 175, slider561.getHeight());
		label561.setLocation(width - 90, label561.getLocation().y);
		slider656.setSize(width- 175, slider656.getHeight());
		label656.setLocation(width - 90, label656.getLocation().y);
		
		lblMaxImageCount.setLocation((width-300)/2, label656.getLocation().y+20);
		tfMaxImageCount.setLocation((width-300)/2 + 120, label656.getLocation().y+20);
		
		btnLaser.setBounds((width-300)/2, label656.getLocation().y+60, 140, 30);
		btnCamera.setBounds((width-300)/2 + 160, label656.getLocation().y+60, 140, 30);
	}

	 /** 
	  * use for the check box
	  */
	public void itemStateChanged(ItemEvent e) {
		this.saveSettings();//here we save the settings all the settings are auto saved
		dstormCtr.refreshLaser();//here we refresh the lasers
	}


	 /**
	  *  use for the slider 350
	  */
	public void stateChanged(ChangeEvent e) {
		JSlider tmp = (JSlider)e.getSource();
		int power = tmp.getValue();
		if(tmp.equals(slider405)){
			label405.setText(power + "%");
		}else if(tmp.equals(slider459)){
			label459.setText(power + "%");
		}else if(tmp.equals(slider488)){
			label488.setText(power + "%");
		}else if (tmp.equals(slider532)){
			label532.setText(power + "%");
		}else if(tmp.equals(slider561)){
			label561.setText(power + "%");
		}else if(tmp.equals(slider656)){
			label656.setText(power + "%");
		}else{
			IJ.log("Wrong laser in DSTORM!");
		}
		this.saveSettings();//here we save the settings all the settings are auto saved
		dstormCtr.refreshLaser();//here we refresh the lasers
	}


	@Override
	public void actionPerformed(ActionEvent arg0) {
		JButton argBtn = (JButton)arg0.getSource();
		if(MyConstants.PSF == 0 && MyConstants.CUR_ALGORITHM == MyConstants.GAUSSIAN_FITTING){
			IJ.error("Enter the PSF", "Please enter the PSF...");//TODO we must change this to make it better
			return;
		}
		if(argBtn.equals(btnLaser)){
			if(isLaserOn){
				powerOffLaser();
			}else{
				powerOnLaser();
			}
		}else{
			if(isTakingData){
				finishTakeData();
			}else{
				startTakeData();
			}
		}
	}

	public void startTakeData(){
		if(!isLaserOn){
			powerOnLaser();
			isLaserOn = true;
		}
		//get the image count
		int count = Integer.MAX_VALUE;
		if(tfMaxImageCount.getText()!=null && !tfMaxImageCount.getText().equals("")){
			try{
				count = Integer.parseInt(tfMaxImageCount.getText());
			}catch(Exception e){
				count = Integer.MAX_VALUE;
			}
		}
		isTakingData = true;
		btnCamera.setIcon(new ImageIcon(MyResource.getYellowButtonBG140()));
		btnCamera.setText("Taking Data");
		dstormCtr.startGettingData(count);

	}
	public void finishTakeData(){
		dstormCtr.stopTakingData();
//		IJ.log("stop......");
		btnCamera.setIcon(new ImageIcon(MyResource.getGreenButtonBG140()));
		btnCamera.setText("No Data");
		isTakingData = false;
		btnCamera.repaint();
	}
	public void powerOnLaser(){
		dstormCtr.powerOnLasers();
		btnLaser.setBorder(null);
		btnLaser.setIcon(new ImageIcon(MyResource.getRedButtonBG140()));
		btnLaser.setText("Laser ON");
		isLaserOn = true;
	}
	public void powerOffLaser(){
		if(isTakingData){
			int result = JOptionPane.showConfirmDialog(IJ.getInstance(),"we are taking data, do you still want to stop?", "Are you sure?",JOptionPane.OK_CANCEL_OPTION);
			if(result == JOptionPane.CANCEL_OPTION){
				return;
			}
		}
		dstormCtr.powerOffLasers();
		btnLaser.setIcon(new ImageIcon(MyResource.getGreenButtonBG140()));
		btnLaser.setText("Laser OFF");
		isLaserOn = false;
	}
	
	public static DStormEditor getInstance(){
		if(instance == null){
			instance = new DStormEditor();
		}
		return instance;
	}
}
